import { NextRequest, NextResponse } from 'next/server'
import { semanticIndexingService } from '@/lib/services/semantic-indexing-service'
import { createServerSupabaseClient } from '@/lib/supabase'
// Create server-side Supabase client with user session
function createSupabaseClient(request: Request) {
// Get the authorization header from the request
const authHeader = request.headers.get('authorization')
return createServerSupabaseClient()
}
export async function POST(
req: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const { query, maxResults = 10, similarityThreshold = 0.01 } = await req.json()
if (!query) {
return NextResponse.json({ error: 'Query is required' }, { status: 400 })
}
const bookId = params.id
const supabase = createSupabaseClient(req)
// Get current user session from auth header
const authHeader = req.headers.get('authorization')
let user
try {
if (authHeader) {
const { data: { user: authUser }, error: authError } = await supabase.auth.getUser(authHeader.replace('Bearer ', ''))
if (!authError) user = authUser
} else {
const { data: { user: sessionUser }, error: sessionError } = await supabase.auth.getUser()
if (!sessionError) user = sessionUser
}
} catch (e) {
// Ignore auth errors
}
if (!user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
// Verify user has access to this book
const { data: book } = await supabase
.from('books')
.select('id')
.eq('id', bookId)
.eq('user_id', user.id)
.single()
if (!book) {
return NextResponse.json({ error: 'Book not found' }, { status: 404 })
}
// Perform semantic search
const results = await semanticIndexingService.semanticSearch(
bookId,
query,
{ maxResults, similarityThreshold }
)
return NextResponse.json({ results })
} catch (error) {
console.error('Semantic search error:', error)
return NextResponse.json(
{ error: 'Failed to perform semantic search' },
{ status: 500 }
)
}
}
export async function GET(
req: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const bookId = params.id
const supabase = createSupabaseClient(req)
// Get current user session from auth header
const authHeader = req.headers.get('authorization')
let user
try {
if (authHeader) {
const { data: { user: authUser }, error: authError } = await supabase.auth.getUser(authHeader.replace('Bearer ', ''))
if (!authError) user = authUser
} else {
const { data: { user: sessionUser }, error: sessionError } = await supabase.auth.getUser()
if (!sessionError) user = sessionUser
}
} catch (e) {
// Ignore auth errors
}
if (!user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
// Verify user has access to this book
const { data: book } = await supabase
.from('books')
.select('id')
.eq('id', bookId)
.eq('user_id', user.id)
.single()
if (!book) {
return NextResponse.json({ error: 'Book not found' }, { status: 404 })
}
// Get indexing status
const { data: statusData } = await supabase
.from('file_embedding_status')
.select(`
file_id,
status,
last_processed_at,
error_message,
file_system_items!inner(name, type)
`)
.eq('book_id', bookId)
const stats = {
totalFiles: 0,
pendingFiles: 0,
processingFiles: 0,
completedFiles: 0,
failedFiles: 0,
files: statusData || []
}
statusData?.forEach((item: any) => {
stats.totalFiles++
switch (item.status) {
case 'pending':
case 'stale':
stats.pendingFiles++
break
case 'processing':
stats.processingFiles++
break
case 'completed':
stats.completedFiles++
break
case 'failed':
stats.failedFiles++
break
}
})
return NextResponse.json({ stats })
} catch (error) {
console.error('Get indexing status error:', error)
return NextResponse.json(
{ error: 'Failed to get indexing status' },
{ status: 500 }
)
}
}